<?php
/**
 * PsiFramework
 *
 * Php Simple Framework
 *
 * PHP version 5.3
 *
 * @category  PsiFramework.Plugins.Form.Classes.DAO
 * @package   PsiFramework.Plugins.Form.Classes.DAO
 * @author    Remi San <remi.san@gmail.com>
 * @copyright 2011 Remi San
 * @license   http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @version   SVN: <svn_id>
 * @link      http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins\Form\Classes\DAO\FormFieldDAO.html
 */

namespace PsiFramework\Plugins\Form\Classes\DAO;

import("Classes.DAO.AbstractDAO");
import("Plugins.Form.Classes.Model.FormField");

use \PsiFramework\Classes\DAO\AbstractDAO;
use \PsiFramework\Classes\Factory\DAOFactory;
use \PsiFramework\Classes\Model\Object;
use \PsiFramework\Classes\Util\Database\Filters\QueryFilter;
use \PsiFramework\Classes\Util\Database\Query\SqlType;
use \PsiFramework\Classes\Util\Database\Query\SqlColumn;
use \PsiFramework\Classes\Util\Database\Query\SqlFunction;
use \PsiFramework\Classes\Util\Database\Query\SqlOperation;
use \PsiFramework\Classes\Util\Database\Query\SqlValue;
use \PsiFramework\Classes\Util\Parameters\ObjectParameters;
use \PsiFramework\Plugins\Form\Classes\Model\FormField;

/**
 * The FormField Data Access Object
 *
 * This is the default class for the FormField Data Access Object
 *
 * @category PsiFramework.Plugins.Form.Classes.DAO
 * @package  PsiFramework.Plugins.Form.Classes.DAO
 * @author   Remi San <remi.san@gmail.com>
 * @license  http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @link     http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins\Form\Classes\DAO\FormFieldDAO.html
 */
class FormFieldDAO extends AbstractDAO
{
    /**
     * @var FormFieldDAO
     */
    protected static $_singleton = null;

    /**
     * The function to update linked forms
     * 
     * @param array $forms The array of forms to update
     * 
     * @return bool
     */
    protected function updateForms(/*array*/ $forms)
    {
        $ok = true ;

        if (!is_null($forms)) {

            $formDao = DAOFactory::getDAO('Form');

            foreach ($forms as $form) {
                $ok = $formDao->save($form);
                if (!$ok) {
                    break;
                }
            }
        }

        return $ok ;
    }

    /**
     * The function to save a FormField
     *
     * @param FormField &$object            The object to save
     * @param bool      $performTransaction Does the save action
     *                                      need a transaction ?
     * @param bool      $checkSecurity      Does the save action
     *                                      need to check the security ?
     *
     * @see AbstractDAO::save()
     *
     * @return bool
     */
    public function save(
        Object    &$object,
        /*bool*/  $performTransaction=true,
        /*bool*/  $checkSecurity=true
    )
    {

        if ($performTransaction) {
            $this->_database->startTransaction();
        }

        $ok = parent::save($object, $performTransaction, $checkSecurity);

        if ($ok) {
            $formDao = DAOFactory::getDAO('Form');

            $formsToUpdate = array();
            $forms = $object->getForms();
            if (!is_null($forms)) {
                foreach ($forms as $formFieldLink) {
                    $form = $formFieldLink->getForm();

                    if (!array_key_exists($form->getName(), $formsToUpdate)) {
                        $formsToUpdate[$form->getName()] = $form ;
                    }
                }
            }

            $ok = $this->updateForms($formsToUpdate);
        }

        if ($performTransaction) {
            if ($ok) {
                $this->_database->commit();
            } else {
                $this->_database->rollback();
            }
        }

        return $ok ;
    }

    /**
     * The function to delete a FormField
     *
     * @param FormField &$object            The object to delete
     * @param bool      $performTransaction Does the delete action
     *                                      need a transaction ?
     * @param bool      $checkSecurity      Does the delete action
     *                                      need to check the security ?
     *
     * @see AbstractDAO::delete()
     *
     * @return bool
     */
    public function delete(
        Object   &$object,
        /*bool*/ $performTransaction=true,
        /*bool*/ $checkSecurity=true
    )
    {

        $formFieldLinkDao = DAOFactory::getDAO('FormFieldLink');

        if ($performTransaction) {
            $this->_database->startTransaction();
        }

        $ok = true ;
        $formsToUpdate = array();
        $forms = $object->getForms();
        if (!is_null($forms)) {
            foreach ($forms as $formFieldLink) {
                $form = $formFieldLink->getForm();

                if (!array_key_exists($form->getName(), $formsToUpdate)) {
                    $formsToUpdate[$form->getName()] = $form ;
                }

                $ok = $formFieldLinkDao->delete(
                    $formFieldLink,
                    false,
                    $checkSecurity
                );
                if (!$ok) {
                    break;
                }
            }
        }

        if ($ok) {
            $ok = $this->updateForms($formsToUpdate);
        }

        if ($ok) {
            $ok = parent::delete($object, false, $checkSecurity);
        }

        if ($performTransaction) {
            if ($ok) {
                $this->_database->commit();
            } else {
                $this->_database->rollback();
            }
        }

        return $ok ;
    }
    
    /**
     * The function to retrieve the FormField by partial name
     * 
     * @param string $partialName The partial name to find
     * 
     * @return array
     */
    public function retrieveByPartialName(/*string*/ $partialName)
    {

        $colNom = new SqlColumn("field_name");
        $value = '%' ;    if (!isNullOrEmptyString($partialName)) {
            $value .= mb_strtoupper($partialName, 'utf-8') . "%" ;
        }
        $sqlValue = new SqlValue($value);

        $upper = new SqlFunction("UPPER");
        $upper->addParameter($colNom);

        $like = new SqlOperation(SqlOperation::$like);
        $like->addParameter($upper);
        $like->addParameter($sqlValue);

        return $this->retrieveAll(new QueryFilter($like));

    }

    /**
     * The function to call instead of the constructor.
     *
     * @param ObjectParameters $objectParameters The object parameters
     *                                           for FormField
     *
     * @return FormFieldDAO
     */
    public static function getInstance(ObjectParameters $objectParameters)
    {

        if (self::$_singleton==null) {
            self::$_singleton = new FormFieldDAO($objectParameters);
        }

        return self::$_singleton;
    }
}
